//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package admin_project_member_api_serv

import (
	"context"

	"atomgit.com/openlinksaas-org/api-server/admin_api_serv/admin_common"
	"atomgit.com/openlinksaas-org/api-server/config"
	"atomgit.com/openlinksaas-org/api-server/dao"
	"atomgit.com/openlinksaas-org/api-server/dao/project_dao"
	"atomgit.com/openlinksaas-org/api-server/dao/user_dao"
	"atomgit.com/openlinksaas-org/proto-gen-go.git/project_member_api"
)

type ProjectMemberAdminApiImpl struct {
	project_member_api.UnimplementedProjectMemberAdminApiServer
	adminCfg *config.AdminCfg
}

func NewProjectMemberAdminApiImpl(adminCfg *config.AdminCfg) *ProjectMemberAdminApiImpl {
	return &ProjectMemberAdminApiImpl{adminCfg: adminCfg}
}

func (apiImpl *ProjectMemberAdminApiImpl) ListRole(ctx context.Context, req *project_member_api.AdminListRoleRequest) (*project_member_api.AdminListRoleResponse, error) {
	emptyList := []*project_member_api.RoleInfo{}

	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &project_member_api.AdminListRoleResponse{
			Code:         project_member_api.AdminListRoleResponse_CODE_WRONG_SESSION,
			ErrMsg:       "会话不存在",
			RoleInfoList: emptyList,
		}, nil
	}
	if !sess.AuthOk {
		return &project_member_api.AdminListRoleResponse{
			Code:         project_member_api.AdminListRoleResponse_CODE_NOT_AUTH,
			ErrMsg:       "未授权会话",
			RoleInfoList: emptyList,
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.ProjectMemberPerm.Read {
		return &project_member_api.AdminListRoleResponse{
			Code:         project_member_api.AdminListRoleResponse_CODE_NO_PERMISSION,
			ErrMsg:       "没有权限",
			RoleInfoList: emptyList,
		}, nil
	}

	exist, err := project_dao.ProjectInfoDao.Exist(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &project_member_api.AdminListRoleResponse{
			Code:         project_member_api.AdminListRoleResponse_CODE_NO_PROJECT,
			ErrMsg:       "项目不存在",
			RoleInfoList: emptyList,
		}, nil
	}

	roleItemList, err := project_dao.MemberRoleDao.ListByProjectId(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}

	infoList := []*project_member_api.RoleInfo{}
	for _, roleItem := range roleItemList {
		infoList = append(infoList, roleItem.ToRoleInfo())
	}

	return &project_member_api.AdminListRoleResponse{
		Code:         project_member_api.AdminListRoleResponse_CODE_OK,
		RoleInfoList: infoList,
	}, nil
}

func (apiImpl *ProjectMemberAdminApiImpl) List(ctx context.Context, req *project_member_api.AdminListRequest) (*project_member_api.AdminListResponse, error) {
	emptyList := []*project_member_api.MemberInfo{}

	sess, ok := dao.CacheDao.GetAdminSession(ctx, req.AdminSessionId)
	if !ok {
		return &project_member_api.AdminListResponse{
			Code:           project_member_api.AdminListResponse_CODE_WRONG_SESSION,
			ErrMsg:         "会话不存在",
			MemberInfoList: emptyList,
		}, nil
	}
	if !sess.AuthOk {
		return &project_member_api.AdminListResponse{
			Code:           project_member_api.AdminListResponse_CODE_NOT_AUTH,
			ErrMsg:         "未授权会话",
			MemberInfoList: emptyList,
		}, nil
	}
	adminUserCfg, err := admin_common.GetAdminUserConfig(ctx, apiImpl.adminCfg, sess.UserName)
	if err != nil {
		return nil, err
	}
	if !adminUserCfg.PermInfo.ProjectMemberPerm.Read {
		return &project_member_api.AdminListResponse{
			Code:           project_member_api.AdminListResponse_CODE_NO_PERMISSION,
			ErrMsg:         "没有权限",
			MemberInfoList: emptyList,
		}, nil
	}

	//读取项目信息
	projectItem, err := project_dao.ProjectInfoDao.Get(ctx, req.ProjectId)
	if err != nil {
		return &project_member_api.AdminListResponse{
			Code:           project_member_api.AdminListResponse_CODE_NO_PROJECT,
			ErrMsg:         "项目不存在",
			MemberInfoList: emptyList,
		}, nil
	}
	//读取角色信息
	roleItemList, err := project_dao.MemberRoleDao.ListByProjectId(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}
	roleItemMap := map[string]*project_dao.RoleInfoDbItem{}
	for _, roleItem := range roleItemList {
		roleItemMap[roleItem.RoleId] = roleItem
	}
	//列出成员
	memberItemList, err := project_dao.MemberInfoDao.ListMember(ctx, req.ProjectId)
	if err != nil {
		return nil, err
	}

	//补充成员信息
	memberUserIdList := []string{}
	for _, memberItem := range memberItemList {
		memberUserIdList = append(memberUserIdList, memberItem.MemberUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, memberUserIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//组装结果
	infoList := []*project_member_api.MemberInfo{}
	for _, memberItem := range memberItemList {
		logoUri := ""
		displayName := ""
		userItem, ok := userItemMap[memberItem.MemberUserId]
		if ok {
			logoUri = userItem.BasicInfo.LogoUri
			displayName = userItem.BasicInfo.DisplayName
		}
		info := memberItem.ToMemberInfo(logoUri, displayName)
		roleItem, ok := roleItemMap[memberItem.RoleId]
		if ok {
			info.RoleName = roleItem.BasicInfo.RoleName
			info.CanAdmin = roleItem.BasicInfo.Admin
		}
		if info.MemberUserId == projectItem.OwnerUserId {
			info.IsProjectOwner = true
			info.CanAdmin = true
		}
		infoList = append(infoList, info)
	}

	return &project_member_api.AdminListResponse{
		Code:           project_member_api.AdminListResponse_CODE_OK,
		MemberInfoList: infoList,
	}, nil
}
